import { Picker, View } from "@tarojs/components";
import {
  AbstractAccordion,
  AbstractButton,
  C26InlineButtonWrapper,
  Calendar,
  WithMargins,
  Icon,
} from "@/components";
import style from "./index.module.scss";
import { CourseFilterShape } from "@/data/courses/courseTypes";
import { useCallback, useRef } from "react";
import {
  CourseApiParams,
  getCourses,
  useApplicationInfo,
} from "@/store/applicationDataContext";
import { DateShape } from "@/data/shared/timeTypes";
import { ActionNames, ActionKeys, sendAction } from "@/utils/tracking";

type CourseFilterTypes = keyof CourseFilterShape;
export type ActiveFilterShape = {
  [key in CourseFilterTypes]: number[]; // ID array
} & {
  dateRange: { start: string; end: string };
};

interface FilterProps {
  filterFields: {
    [key in CourseFilterTypes]: {
      id: number;
      asString: string;
      status: boolean;
    }[];
  };
  activeFilters: ActiveFilterShape;
  activeFilterSetter: React.Dispatch<React.SetStateAction<ActiveFilterShape>>;
  showFilterSetter: React.Dispatch<React.SetStateAction<boolean>>;
}

// Inline component for re-use
const ButtonGroup = ({
  filterCategory,
  filterFields,
  activeFilters,
  activeFilterSetter,
}: { filterCategory: CourseFilterTypes } & Omit<
  FilterProps,
  "showFilterSetter"
>) => {
  const toggleFilterId = useCallback(
    (filterCategory: CourseFilterTypes, id: number) => {
      activeFilterSetter((prevState) => ({
        ...prevState,
        [filterCategory]: prevState[filterCategory].includes(id)
          ? prevState[filterCategory].filter((val) => val !== id)
          : [...prevState[filterCategory], id],
      }));
    },
    [activeFilterSetter]
  );

  return (
    <View className={`${style["button-row"]}`}>
      {filterFields[filterCategory]
        .filter((categoryObj) => categoryObj.status)
        .map((categoryObj, categoryObjIdx) => (
          <C26InlineButtonWrapper key={`${filterCategory}-${categoryObjIdx}`}>
            <AbstractButton
              color={
                activeFilters[filterCategory].includes(categoryObj.id)
                  ? "viking"
                  : "viking-inactive"
              }
              onClick={() => toggleFilterId(filterCategory, categoryObj.id)}
            >
              {categoryObj.asString}
            </AbstractButton>
          </C26InlineButtonWrapper>
        ))}
    </View>
  );
};

const ALL_DURATION_TAG = "所有";

const C21Filter = ({
  filterFields,
  activeFilters,
  activeFilterSetter,
  showFilterSetter,
}: FilterProps) => {
  const { dispatch } = useApplicationInfo();
  const calendarRef: any = useRef();

  const resetCalendar = () => {
    calendarRef!.current!.reset();
  };

  const durationArr = [
    {
      formattedString: ALL_DURATION_TAG,
      id: null,
      asString: ALL_DURATION_TAG,
      status: true,
    },
    ...filterFields.routine_course_duration
      .filter((durObj) => durObj.status)
      .map((durObj) => ({
        ...durObj,
        formattedString: `${durObj.asString}小时`,
      })),
  ];

  const getFilteredCourses = () => {
    const params: CourseApiParams = {};

    // Course types
    if (activeFilters.routine_course_category.length) {
      params.courseTypeIds = activeFilters.routine_course_category.join(",");
    }

    // Languages
    if (activeFilters.routine_course_language.length) {
      params.courseLanguageIds =
        activeFilters.routine_course_language.join(",");
    }

    // Prices
    if (activeFilters.routine_course_price.length) {
      params.coursePriceIds = activeFilters.routine_course_price.join(",");
    }

    // Date range
    if (activeFilters.dateRange.start) {
      params.courseInterval = `${activeFilters.dateRange.start as DateShape},${
        (activeFilters.dateRange.end
          ? activeFilters.dateRange.end
          : activeFilters.dateRange.start) as DateShape
      }`;
    }

    // Course duration
    if (activeFilters.routine_course_duration.length) {
      params.courseDurationIds =
        activeFilters.routine_course_duration.join(",");
    }

    sendAction(ActionNames.CourseApplyClick, {
      [ActionKeys.CourseDate]: activeFilters.dateRange.start + "-" + activeFilters.dateRange.end,
      [ActionKeys.CourseType]: activeFilters.routine_course_category,
      [ActionKeys.CourseLanguage]: activeFilters.routine_course_language,
      [ActionKeys.CoursePrice]: activeFilters.routine_course_price,
      [ActionKeys.CourseDuration]: activeFilters.routine_course_duration,
    });

    getCourses(dispatch, params);
    showFilterSetter(false);
  };

  return (
    <View className={style["filter-content"]}>
      <WithMargins>
        <View className={style["calendar-header"]}>
          <View>课程日期</View>
          <View
            className={style["clear-calendar"]}
            onClick={() => {
              resetCalendar();
              activeFilterSetter((prevActiveFilters) => ({
                ...prevActiveFilters,
                dateRange: { start: "", end: "" },
              }));
            }}
          >
            清空筛选条件
          </View>
        </View>
        <View className={style["accordion-wrapper"]}>
          <AbstractAccordion title="选取日期" notoSans smallTitle>
            <View>
              <Calendar
                ref={calendarRef}
                range
                onSelectDate={(dateRange) => {
                  activeFilterSetter((prevActiveFilters) => ({
                    ...prevActiveFilters,
                    dateRange,
                  }));
                }}
              />
            </View>
          </AbstractAccordion>
        </View>

        {/* Course-types */}
        <View className={style.tag}>课程类型</View>
        <ButtonGroup
          filterCategory="routine_course_category"
          filterFields={filterFields}
          activeFilters={activeFilters}
          activeFilterSetter={activeFilterSetter}
        />

        {/* Language */}
        <View className={style.tag}>课程语言</View>
        <ButtonGroup
          filterCategory="routine_course_language"
          filterFields={filterFields}
          activeFilters={activeFilters}
          activeFilterSetter={activeFilterSetter}
        />

        {/* Price */}
        <View className={style.tag}>课程价格</View>
        <ButtonGroup
          filterCategory="routine_course_price"
          filterFields={filterFields}
          activeFilters={activeFilters}
          activeFilterSetter={activeFilterSetter}
        />

        {/* Duration */}
        <View className={style["picker-wrapper"]}>
          <View className={style.tag}>课程时长</View>
          <Picker
            onChange={(event) => {
              const selected = durationArr[event.detail.value];
              if (selected.id === null) {
                activeFilterSetter((prevFilterVals) => ({
                  ...prevFilterVals,
                  routine_course_duration: [],
                }));
              } else {
                activeFilterSetter((prevFilterVals) => ({
                  ...prevFilterVals,
                  routine_course_duration: [selected.id],
                }));
              }
            }}
            range={durationArr.map((durObj) => durObj.formattedString)}
          >
            <View className={style.picker}>
              <View className={style.text}>
                {activeFilters.routine_course_duration.length
                  ? durationArr.find(
                      (durationData) =>
                        durationData.id ===
                        activeFilters.routine_course_duration[0]
                    )?.formattedString
                  : ALL_DURATION_TAG}
              </View>
              <Icon type="DownChevron" className={style.chevron} />
            </View>
          </Picker>
        </View>
      </WithMargins>

      {/* Bottom CTA buttons */}
      <View className={style.ctas}>
        <AbstractButton
          color="transparent"
          onClick={() => {
            activeFilterSetter({
              dateRange: { start: "", end: "" },
              routine_course_category: [],
              routine_course_duration: [],
              routine_course_language: [],
              routine_course_price: [],
            });
            resetCalendar();
          }}
        >
          重置
        </AbstractButton>
        <AbstractButton color="dark" onClick={getFilteredCourses}>
          应用
        </AbstractButton>
      </View>
    </View>
  );
};

export default C21Filter;
